/***********************************************************
 * Author: 	Brandon McKune
 * E-Mail:	bmckune.cs@gmail.com
 * Date:	September 2, 2011
 * Class:	Advanced OS
 * Time:	1150 - 1325
 * Smstr:	Fall 2011
 */

#ifndef CLSCHEDULER_CPP_
#define CLSCHEDULER_CPP_

#include <queue>

#include "includes.h"
#include "ClTask.h"
#include "ClRTClock.h"
#include "Utilities.h"

class ClScheduler{
public:
	enum EnumSchedulerType{ BASE, INTERMEDIATE, FULL };
	static ClScheduler* getInstance();
	~ClScheduler();

	//Scheduling functions
	void setupScheduler(uint64_t numProcs, uint64_t maxProcRateHz);
	void setupScheduler(uint64_t numProcs, uint64_t *maxProcRateHz);
	void runScheduler(EnumSchedulerType SchedulingType, vector<ClTask> *taskInterrupts);
	void printReadyQueue();
	void printRunningQueue();
	void printFinishedQueue();

	bool hasTasksWaiting();

	void runBaseScheduler(vector<ClTask> *taskInterrupts);
	void runIntermediateScheduler(vector<ClTask> *taskInterrupts);
	void runFullScheduler(vector<ClTask> *taskInterrupts);

	void processInterrupts(vector<ClTask> *taskInterrupts);
	void updateRunningQueuePreSched();
	void updateRunningQueuePostSched();
	void updateEnergyConsumed();
	void updateAverageProcRate();
	void updateTaskInstructionCounter();
	void updateProcessorUtilizationArray();
	bool insertToReadyQueue(ClTask task);
	bool insertToRunningQueue(ClTask task);
	void insertTask(vector<ClTask> *queue, ClTask task);
	void printQueue(vector<ClTask> *queue);

	//Intermediate & Full Scheduler
	void updateActiveProcessorsPreschedule();
	void updateActiveProcessorsRuntime();
	void updateActiveProcessorRates();
protected:
private: //
	ClScheduler();
	static ClScheduler *m_ptrClScheduler;

	std::vector<ClTask> m_ptrReadyQueue;// = new std::queue<ClTask*>();
	std::vector<ClTask> m_ptrRunningQueue;
	std::vector<ClTask> m_ptrFinishedQueue;// = new std::queue<ClTask*>();

	//processor utilization array
	double *m_ptrDbProcessorsRateArr;
	//Max processor speed array
	uint64_t *m_ptrMaxProcessorsRateArr;

	uint64_t m_uint64NumProcessors;
	double m_dbEnergyConsumed;
	double m_dbAverageProcRate;

	bool m_boolSchedulerSetup;
	EnumSchedulerType m_enumSchedulerType;
	//Based on the paper
};

#endif /* CLSCHEDULER_CPP_ */
